package com.gavin.plugin.service.impl;

import com.gavin.model.Model;
import com.gavin.model.Result;
import com.gavin.plugin.database.DataEngineList;
import com.gavin.plugin.service.ITransPlugin;
import com.gavin.schema.dataservice.DataService;
import com.gavin.schema.service.Parameter;
import com.gavin.schema.service.ServiceConfig;
import com.gavin.utils.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;

//import org.apache.log4j.Logger;

/**
 * ------------------------------
 * 事务插件
 * ------------------------------
 * @author wdm（l311576@sina.com）  @date 2018年6月25日
 * @version 1.0
 */
public class TransPlugin implements ITransPlugin {
	static Logger logger = LoggerFactory.getLogger(TransPlugin.class);

	private HashMap<String, String> hmParameterMap;// 配置参数
	private HashMap<String, DataEngineList> hmAllDataGroup;// 关系数据库引擎容器
	private HashMap<String, TransService> hmService;
	private String strPluginName;

	public TransPlugin() {
		hmService = new HashMap<String, TransService>(3);
		hmParameterMap = new HashMap<String, String>(10);
		hmAllDataGroup = new HashMap<String, DataEngineList>();
	}
	
	public void setParameterMap(HashMap<String, String> hmParameterMap) {
		this.hmParameterMap = hmParameterMap;
	}

	public void setPublicDataGroup(HashMap<String, DataEngineList> hmPublicDataGroup) {
		hmAllDataGroup.putAll(hmPublicDataGroup);
	}

	public String getPluginName() {
		return strPluginName;
	}

	public void setPluginName(String strPluginName) {
		this.strPluginName = strPluginName;
	}

	public void init(String strPluginName, TransBus transBus, com.gavin.schema.service.ServicePlugin pluginDefine, ClassLoader classLoader) throws Exception {
		if (classLoader == null) {
			classLoader = this.getClass().getClassLoader();
		}

//		this.transBus = transBus;
		this.strPluginName = strPluginName;
		// 初始化插件参数
		int nParameterCount = pluginDefine.getParameterCount();
		for (int i = 0; i < nParameterCount; i++) {
			Parameter para = pluginDefine.getParameter(i);
			this.hmParameterMap.put(para.getName(), para.getValue());
		}

		try {
			ServiceConfig[] serviceConfigs = pluginDefine.getServiceConfig();
			if (serviceConfigs == null) {
				serviceConfigs = new ServiceConfig[0];
			}
			for (ServiceConfig sc : serviceConfigs) {
				TransService transService = new TransService(sc.getName(), this, transBus);

				String strKey = sc.getName().toLowerCase();
				if (this.hmService.containsKey(strKey) == true) {
					throw new Exception("Service name already exists: " + sc.getName());
				}
				if (transBus.addService(transService) == null) {
					throw new Exception("Service name already exists: " + sc.getName());
				}
				this.hmService.put(strKey, transService);

				// DataService
				if (sc.getDataService() != null) {
					com.gavin.schema.service.DataService dataServiceDefine = sc.getDataService();
					if (logger.isInfoEnabled()) {
						logger.info("Loading data service: " + dataServiceDefine.getResource());
					}

					String strSQLTransXML = IOUtils.readTextResource(dataServiceDefine.getResource(),
							dataServiceDefine.getEncoding(), classLoader);
					if (strSQLTransXML == null) {
						throw new Exception("Invalid data service: " + dataServiceDefine.getResource());
					}

					DataService dataService = null;
					try {
						dataService = DataService.fromXML(strSQLTransXML);
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
						throw new Exception("Invalid data service xml: " + dataServiceDefine.getResource());
					}
					Result ret = dataService.init(sc.getName(), this, transBus);
					if (ret.getCode() != 0) {
						throw new Exception("Loading data service " + dataServiceDefine.getResource() + " failed, " + ret.getText());
					}
					dataService.setDataGroupSet(this.hmAllDataGroup);

					transService.setDataService(dataService);
				}
			}
		} catch (Exception e) {
			this.destroy();
			throw e;
		}
	}

	public void destroy() {
		this.hmService.clear();
		this.hmAllDataGroup.clear();
		this.hmParameterMap.clear();
	}
	
	public String getParameter(String strName, String strDefaultValue) {
		String strValue = hmParameterMap.get(strName);
		if (strValue == null) {
			return strDefaultValue;
		}
		return strValue;
	}

	public String getParameter(String strName) {
		return hmParameterMap.get(strName);
	}
}
